package com.marvels.financial.pay.bfpay.service.impl;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.UUID;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.marvels.common.constants.MarvelsConstant;
import com.marvels.common.dto.pay.McfeRepaymentTradeDetails;
import com.marvels.common.exception.MarvelsBusinessException;
import com.marvels.common.utils.BeanUtils;
import com.marvels.common.utils.DateUtils;
import com.marvels.common.utils.HttpUtils;
import com.marvels.common.utils.MarvelsLogUtil;
import com.marvels.common.utils.ServerProperties;
import com.marvels.financial.consum.FinancialConsumerApproveApi;
import com.marvels.financial.consum.FinancialConsumerLoanApplyApi;
import com.marvels.financial.loan.dao.McfeCustomerLoanContractDao;
import com.marvels.financial.loan.dao.McfeLendingProcessDao;
import com.marvels.financial.loan.dao.McfePaymentWithholdDao;
import com.marvels.financial.loan.dao.McfePaymentWithholdDetailDao;
import com.marvels.financial.loan.dto.McamLoanApplyInfoDTO;
import com.marvels.financial.loan.dto.McfeCustomerLoanContractDTO;
import com.marvels.financial.loan.dto.McfeLendingProcess;
import com.marvels.financial.loan.dto.McfePaymentWithholdDTO;
import com.marvels.financial.loan.dto.McfePaymentWithholdDetailDTO;
import com.marvels.financial.loan.service.LoanAuditApi;
import com.marvels.financial.loan.service.LoanPaymentApi;
import com.marvels.financial.loan.service.WithholdPaymentApi;
import com.marvels.financial.pay.bfpay.dto.BaoFuBindCardDTO;
import com.marvels.financial.pay.bfpay.dto.BaoFuDirectPaymentDTO;
import com.marvels.financial.pay.bfpay.dto.BaoFuDirectPaymentQueryDTO;
import com.marvels.financial.pay.bfpay.dto.BaoFuPayTradeDTO;
import com.marvels.financial.pay.bfpay.dto.BaoFuPayTradeResponse;
import com.marvels.financial.pay.bfpay.dto.BaoFuPayTradeResponse.TransContent.TransReqDatas.TransReqData;
import com.marvels.financial.pay.bfpay.dto.BaoFuPayTradeStrtusQueryDTO;
import com.marvels.financial.pay.bfpay.dto.BaoFuPrebindCardDTO;
import com.marvels.financial.pay.bfpay.dto.BfPaymentCallBackContentDTO;
import com.marvels.financial.pay.bfpay.dto.BfPaymentCallBackDTO;
import com.marvels.financial.pay.bfpay.dto.BfPaymentNotifyDTO;
import com.marvels.financial.pay.bfpay.dto.WithHoldTradeDTO;
import com.marvels.financial.pay.bfpay.service.BfPayApi;
import com.marvels.financial.pay.dao.McfeRepaymentTradeDetailsMapper;
import com.marvels.financial.utils.Base64Util;
import com.marvels.financial.utils.FormatUtil;
import com.marvels.financial.utils.RsaCodingUtil;
import com.marvels.financial.utils.SecurityUtil;
import com.marvels.financial.utils.SignatureUtils;
import com.marvels.financial.utils.SystemUtil;
import com.marvels.system.common.dao.McsmRevealConfigureAppDao;
import com.marvels.system.common.dto.McsmRevealConfigureAppDTO;

import cn.hutool.core.util.StrUtil;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

@Service
public class BfpayImpl implements BfPayApi{
	
	@Value("${config.properties.path}")
	private  String configPropertiesPath;
	
	@Autowired
	private McsmRevealConfigureAppDao mcsmRevealConfigureAppDao;
	
	@Autowired
	private McfePaymentWithholdDetailDao detailDao;
	
	@Autowired
	private McfeCustomerLoanContractDao contractDao;
	
	@Autowired
	private McfePaymentWithholdDao withholdDao;
	
	@Autowired
	private WithholdPaymentApi withholdPaymentApi;

	@Autowired
	private McfeLendingProcessDao mcfeLendingProcessMapper;

	@Autowired
	private FinancialConsumerLoanApplyApi consumerLoanApplyApi;
	
	@Autowired
	private McfeRepaymentTradeDetailsMapper mcamRepaymentTradeDetailsMapper;
	
	@Autowired
	private FinancialConsumerApproveApi consumerApproveApi;
	
	@Autowired
	private LoanPaymentApi loanPaymentApi;
	
	@Autowired
	private LoanAuditApi loanAuditApi;
	
	@Override
	public Map<String, Object> baoFuPrebindCard(BaoFuPrebindCardDTO bindCardDTO) throws MarvelsBusinessException {
		MarvelsLogUtil.getInstance().info(">>>>>>>>>>预绑卡请求参数:" + JSON.toJSONString(bindCardDTO));
		String userId = bindCardDTO.getUserId();// 用户ID
		String cardType = bindCardDTO.getCardType();// 默认 // :101 // 借记卡
		String bankNumber = bindCardDTO.getBankNumber();// 银行卡号
		String realName = bindCardDTO.getRealName();// 持卡人姓名
		String idNumber = bindCardDTO.getIdNumber();// 身份证
		String mobile = bindCardDTO.getMobile();// 手机号
		String orderNumber = bindCardDTO.getOrderNumber();
		if(StringUtils.isEmpty(bankNumber)){
			throw new MarvelsBusinessException("银行卡号不能为空");
		}
		if(StringUtils.isEmpty(realName)){
			throw new MarvelsBusinessException("持卡人姓名不能为空");
		}
		if(StringUtils.isEmpty(mobile)){
			throw new MarvelsBusinessException("手机号不能为空");
		}
		if(StringUtils.isEmpty(idNumber)){
			throw new MarvelsBusinessException("身份证不能为空");
		}
		if(StringUtils.isEmpty(orderNumber)){
			throw new MarvelsBusinessException("订单号不能为空");
		}
		//参数
		//0 是分账版  1 是普通版
		String version =ServerProperties.getValue(configPropertiesPath, "common.properties", "bf.version");
		if(StrUtil.isEmpty(version)){
			version = "1";
		}
		String pfxPath =ServerProperties.getValue(configPropertiesPath, "common.properties", "bf.pfx.path");
		String cerPath=ServerProperties.getValue(configPropertiesPath, "common.properties", "bf.cer.path");
		String terminalId =getBfTerminalId();
		String memberId=getBfMemberId();
		String priKeyPass=getBfPriKeypass();
		String aes =getBfAesKey();
		String requestUrl=ServerProperties.getValue(configPropertiesPath, "common.properties", "bf.xy.request.url");
		String dgtlEnvlp = "01" + "|" + aes;
		String accInfo = bankNumber + "|" + realName + "|" + idNumber + "|" + mobile + "|" + "" + "|" + "";
		Map<String, String> hashMap = new TreeMap<String, String>();
		hashMap.put("send_time",DateUtils.getDateYYYYMMDDHHMMSS(new Date()));// 报文发送日期时间
		hashMap.put("msg_id", orderNumber);// 商户流水号
		hashMap.put("version", "4.0.0.0");// 版本号
		// hashMap.put("terminal_id", thirdProperties.getBf_terminal_id());//终端号
		hashMap.put("terminal_id",terminalId);// 终端号
		if("0".equals(version)){
			hashMap.put("txn_type", "11");// 交易类型 协议支付预绑卡类交易
		}else{
			hashMap.put("txn_type", "01");// 交易类型 协议支付预绑卡类交易
		}
		// hashMap.put("member_id", thirdProperties.getBf_member_id());//商户号
		hashMap.put("member_id", memberId);// 商户号
		try {
			hashMap.put("dgtl_envlp", RsaCodingUtil.encryptByPubCerFile(SecurityUtil.Base64Encode(dgtlEnvlp), cerPath));
		} catch (UnsupportedEncodingException e) {
			MarvelsLogUtil.getInstance().error(">>>>>>>>>>orderNumber"+orderNumber+"预绑卡dgtl_envlp字段加密异常:", e);
			throw new MarvelsBusinessException("dgtl_envlp字段加密异常");
		} // 数字信封
		hashMap.put("user_id", userId);// 用户id
		hashMap.put("card_type", cardType);// 卡类型
		hashMap.put("id_card_type", "01");// 证件类型 默认身份证
		try {
			hashMap.put("acc_info", SecurityUtil.AesEncrypt(SecurityUtil.Base64Encode(accInfo), aes));
		} catch (UnsupportedEncodingException e) {
			MarvelsLogUtil.getInstance().error(">>>>>>>>>>orderNumber"+orderNumber+"预绑卡acc_info字段aes加密异常:", e);
			throw new MarvelsBusinessException("acc_info字段加密异常");
		} // 账户信息
		hashMap.put("req_reserved1", orderNumber);// 商户保留域1
		String str = FormatUtil.coverMap2String(hashMap);
		String sign = "";
		try {
			String signature = SecurityUtil.sha1X16(str, "UTF-8");// 签名
			sign = SignatureUtils.encryptByRSA(signature, pfxPath, priKeyPass);
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error(">>>>>>>>>>预绑卡signature字段rsa加密异常:", e);
			throw new MarvelsBusinessException("signature字段rsa加密异常");
		}
		hashMap.put("signature", sign);// 签名域
		String resultStr = "";
		try {
			MarvelsLogUtil.getInstance().info(">>>>>>>>>>>>>宝付预绑卡请求参数:" + JSON.toJSONString(hashMap));
			resultStr = HttpUtils.RequestForm(requestUrl, hashMap);
			MarvelsLogUtil.getInstance().info(">>>>>>>>>>>>>宝付预绑卡返回参数:" + resultStr);
		} catch (Exception e1) {
			MarvelsLogUtil.getInstance().error(">>>>>>>>>orderNumber" + orderNumber + ",idNumber" + idNumber + "预绑卡请求异常:", e1);
			throw new MarvelsBusinessException("预绑卡请求异常");
		}
		String respCode = "";
		String bizRespCode = "";
		String bizRespMsg = "";
		String uniqueCode = "";
		Map<String, Object> result=new HashMap<String, Object>();
		if (StringUtils.isNotEmpty(resultStr)) {
			Map<String, String> returnData = FormatUtil.getParm(resultStr);
			// 返回数据校验签名部分
			String signature = returnData.get("signature");
			returnData.remove("signature");// 移除签名字段
			String returnDataStr = FormatUtil.coverMap2String(returnData);
			String loginSignature = "";
			try {
				loginSignature = SecurityUtil.sha1X16(returnDataStr, "UTF-8");
			} catch (Exception e) {
				MarvelsLogUtil.getInstance().error(">>>>>>>>>orderNumber" + orderNumber + ",idNumber" + idNumber + "预绑卡返回结果加签异常:", e);
			} // 签名
			if (SignatureUtils.verifySignature(cerPath, loginSignature, signature)) {// 签名一致
				respCode = returnData.get("resp_code");// 应答码
				bizRespCode = returnData.get("biz_resp_code");// 业务应答码
				bizRespMsg = returnData.get("biz_resp_msg");// 业务返回说明
				String rDgtlEnvlp = "";
				String rAesKey = "";
				try {
					rDgtlEnvlp = SecurityUtil.Base64Decode(
							RsaCodingUtil.decryptByPriPfxFile(returnData.get("dgtl_envlp"), pfxPath, priKeyPass));
					rAesKey = FormatUtil.getAesKey(rDgtlEnvlp);
				} catch (Exception e) {
					MarvelsLogUtil.getInstance().error(">>>>>>>宝付预绑卡解签:",e);
					throw new MarvelsBusinessException("解签异常");
				}
				uniqueCode = returnData.get("unique_code");// 预签约唯一码
				if ("S".equalsIgnoreCase(respCode)) {// 成功
					try {
						result.put("uniqueCode", SecurityUtil.Base64Decode(SecurityUtil.AesDecrypt(uniqueCode, rAesKey)));
					} catch (Exception e) {
						MarvelsLogUtil.getInstance().error(">>>>>>>宝付预绑卡uniqueCode解签:",e);
						throw new MarvelsBusinessException("uniqueCode解签异常");
					}
					result.put("errormsg","成功");
					result.put("status","TO_VALIDATE");//沿用易宝的预绑卡订单状态  TO_VALIDATE  待短验
				} else {// 失败
					result.put("errormsg",bizRespMsg);
					result.put("status","BIND_FAIL");
				}
				result.put("errorcode",respCode);
			} else {
				throw new MarvelsBusinessException("签名不一致");
			}
		}else{
			throw new MarvelsBusinessException("返回结果为空");
		}
		return result;
	}

	@Override
	public Map<String, Object> baoFuBindCard(BaoFuBindCardDTO bindCardDTO) throws MarvelsBusinessException {
		MarvelsLogUtil.getInstance().info(">>>>>>>>>>确定绑卡请求参数:" + JSON.toJSONString(bindCardDTO));
		//1 获取所需参数
		String smsCode = bindCardDTO.getSmsCode();// 短信验证码
		String orderNumber =bindCardDTO.getOrderNumber();
		String uniqueCode = bindCardDTO.getUniqueCode();
		if(StringUtils.isEmpty(smsCode)){
			throw new MarvelsBusinessException("验证码不能为空");
		}
		if(StringUtils.isEmpty(orderNumber)){
			throw new MarvelsBusinessException("订单号不能为空");
		}
		if(StringUtils.isEmpty(uniqueCode)){
			throw new MarvelsBusinessException("预签约唯一码不能为空");
		}
		//参数
		//0 是分账版  1 是普通版
		String version =ServerProperties.getValue(configPropertiesPath, "common.properties", "bf.version");
		if(StrUtil.isEmpty(version)){
			version = "1";
		}
		String pfxPath =ServerProperties.getValue(configPropertiesPath, "common.properties", "bf.pfx.path");
		String cerPath=ServerProperties.getValue(configPropertiesPath, "common.properties", "bf.cer.path");
		String terminalId =getBfTerminalId();
		String memberId=getBfMemberId();
		String priKeyPass=getBfPriKeypass();
		String aes =getBfAesKey();
		String requestUrl=ServerProperties.getValue(configPropertiesPath, "common.properties", "bf.xy.request.url");
		String dgtlEnvlp = "01" + "|" + aes;
		Map<String, String> hashMap = new TreeMap<String, String>();
		hashMap.put("send_time", DateUtils.getDateYYYYMMDDHHMMSS(new Date()));// 报文发送日期时间
		hashMap.put("msg_id", orderNumber);// 商户流水号
		hashMap.put("version", "4.0.0.0");// 版本号
		hashMap.put("terminal_id", terminalId);// 终端号
		if("0".equals(version)){
			hashMap.put("txn_type", "12");// 交易类型 协议支付预绑卡类交易
		}else{
			hashMap.put("txn_type", "02");// 交易类型 协议支付确认绑卡类交易
		}
		hashMap.put("member_id",memberId);// 商户号
		try {
			hashMap.put("dgtl_envlp", RsaCodingUtil.encryptByPubCerFile(SecurityUtil.Base64Encode(dgtlEnvlp), cerPath));
		} catch (UnsupportedEncodingException e) {
			MarvelsLogUtil.getInstance().error(">>>>>>>>>>预绑卡dgtl_envlp字段加密异常:", e);
		}
		try {
			hashMap.put("unique_code",
					SecurityUtil.AesEncrypt(SecurityUtil.Base64Encode(uniqueCode + "|" + smsCode), aes));
		} catch (UnsupportedEncodingException e) {
			MarvelsLogUtil.getInstance().error(">>>>>>>>>>确定绑卡unique_code字段aes加密异常:", e);
		}
		// 账户信息
		hashMap.put("req_reserved1", orderNumber);// 商户保留域1
		String str = FormatUtil.coverMap2String(hashMap);
		String sign = "";
		try {
			String signature = SecurityUtil.sha1X16(str, "UTF-8");// 签名
			sign = SignatureUtils.encryptByRSA(signature, pfxPath, priKeyPass);
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error(">>>>>>>>>>确定绑卡signature字段rsa加密异常:", e);
		}
		hashMap.put("signature", sign);// 签名域
		String resultStr = "";
		try {
			//3.2 绑卡请求
			MarvelsLogUtil.getInstance().info(">>>>>>>>>>>>>宝付确定绑卡请求参数:" + JSON.toJSONString(hashMap));
			resultStr = HttpUtils.RequestForm(requestUrl, hashMap);
			MarvelsLogUtil.getInstance().info(">>>>>>>>>>>>>宝付确定绑卡返回参数:" + JSON.toJSONString(resultStr));
		} catch (Exception e1) {
			MarvelsLogUtil.getInstance().error(">>>>>>>>>orderNumber" + orderNumber + "确定绑卡请求异常:", e1);
		}
		//3.3.2 验证签名，并解析结果
		String respCode = "";
		String bizRespCode = "";
		String bizRespMsg = "";
		String protocolNo = "";
		Map<String, Object> result=new HashMap<String, Object>();
		if (StringUtils.isNotEmpty(resultStr)) {
			Map<String, String> returnData = FormatUtil.getParm(resultStr);
			// 返回数据校验签名部分
			String signature = returnData.get("signature");
			returnData.remove("signature");// 移除签名字段
			String returnDataStr = FormatUtil.coverMap2String(returnData);
			String loginSignature = "";
			try {
				loginSignature = SecurityUtil.sha1X16(returnDataStr, "UTF-8");
			} catch (Exception e) {
				MarvelsLogUtil.getInstance().error(">>>>>>>>>orderNumber" + orderNumber  + "确定绑卡返回结果加签异常:", e);
			} // 签名
			if (SignatureUtils.verifySignature(cerPath, loginSignature, signature)) {// 签名一致
				respCode = returnData.get("resp_code");// 应答码
				bizRespCode = returnData.get("biz_resp_code");// 业务应答码
				bizRespMsg = returnData.get("biz_resp_msg");// 业务返回说明
				String rDgtlEnvlp="";
				String rAesKey="";
				try {
					rDgtlEnvlp = SecurityUtil.Base64Decode(
							RsaCodingUtil.decryptByPriPfxFile(returnData.get("dgtl_envlp"), pfxPath, priKeyPass));
					rAesKey = FormatUtil.getAesKey(rDgtlEnvlp);
				} catch (Exception e) {
					MarvelsLogUtil.getInstance().error(">>>>>>>宝付绑卡解签:",e);
					throw new MarvelsBusinessException("解签异常");
				}
				protocolNo = returnData.get("protocol_no");// 签约协议号
				if ("S".equalsIgnoreCase(respCode)) {// 成功
					try {
						result.put("signedId",SecurityUtil.Base64Decode(SecurityUtil.AesDecrypt(protocolNo, rAesKey)));
					} catch (Exception e) {
						MarvelsLogUtil.getInstance().error(">>>>>>>宝付绑卡uniqueCode解签:",e);
						throw new MarvelsBusinessException("uniqueCode解签异常");
					}
					result.put("errormsg","成功");
					result.put("status","BIND_SUCCESS");
				} else{// 失败
					result.put("errormsg",bizRespMsg);
					result.put("status","BIND_FAIL");
				} 
				result.put("errorcode",respCode);
			} else {
				throw new MarvelsBusinessException("签名不一致");
		
			}
		}else{
			throw new MarvelsBusinessException("返回结果为空");
		}
		return result;
	}

	@Override
	public Map<String, Object> baoFuPayTrade(BaoFuPayTradeDTO baoFuPayTradeDTO) throws MarvelsBusinessException {
		Map<String, Object> hashMap = new HashMap<String, Object>();
		hashMap.put("member_id", getBfMemberId());
		hashMap.put("terminal_id", getBfTerminalId());
		hashMap.put("data_type", "json");
		hashMap.put("version", "4.0.0");
		JSONArray transReqData = new JSONArray();
		String orderNumber = baoFuPayTradeDTO.getOrderNumber();
		String toAccName = baoFuPayTradeDTO.getToAccName();// 收款人姓名
		String toAccNo = baoFuPayTradeDTO.getToAccNo();// 收款人银行帐号
		String toBankName = baoFuPayTradeDTO.getToBankName();
		JSONObject obj = new JSONObject();
		obj.put("trans_no", orderNumber);
		obj.put("trans_money", baoFuPayTradeDTO.getTransMoney());
		obj.put("to_acc_name", toAccName);
		obj.put("to_acc_no", toAccNo);
		obj.put("to_bank_name", toBankName);
		obj.put("to_pro_name", baoFuPayTradeDTO.getToProName());
		obj.put("to_city_name", baoFuPayTradeDTO.getToCityName());
		obj.put("to_acc_dept", baoFuPayTradeDTO.getToAccDept());
		obj.put("trans_summary", baoFuPayTradeDTO.getTransSummary());
		obj.put("trans_card_id", baoFuPayTradeDTO.getTransCardId());
		obj.put("trans_mobile", baoFuPayTradeDTO.getTransMobile());
		transReqData.add(obj);
		JSONObject transReqData2 = new JSONObject();
		transReqData2.put("trans_reqData", transReqData);
		JSONArray transReqDatas = new JSONArray();
		transReqDatas.add(transReqData2);
		JSONObject transContent = new JSONObject();
		transContent.put("trans_reqDatas", transReqDatas);
		JSONObject transContent2 = new JSONObject();
		transContent2.put("trans_content", transContent);
		String base64Str = "";
		try {
			base64Str = Base64Util.getBASE64(transContent2.toString());
		} catch (UnsupportedEncodingException e1) {
			MarvelsLogUtil.getInstance().error(">>>>>>>>宝付代付base64编码", e1);
			throw new MarvelsBusinessException("代付base64编码异常");
		}
		String pfxPath = ServerProperties.getValue(configPropertiesPath, "common.properties", "bf.pfx.path");
		String cerPath = ServerProperties.getValue(configPropertiesPath, "common.properties", "bf.cer.path");
		String bfPayUrl = ServerProperties.getValue(configPropertiesPath, "common.properties", "bf_pay_Url");
		String encryptStr = RsaCodingUtil.encryptByPriPfxFile(base64Str, pfxPath, getBfPriKeypass());
		hashMap.put("data_content", encryptStr);
		String str = SystemUtil.paramsAssembling(hashMap, bfPayUrl);
		MarvelsLogUtil.getInstance().info(">>>>>>>>代付交易请求参数" + str);
		String resultStr="";
		Map<String, Object> result=new HashMap<String, Object>();
		try {
			resultStr = HttpUtils.baoFuHttpRequest(str);
		} catch (Exception e1) {
			result.put("status",MarvelsConstant.PROCESSING);
			result.put("errormsg","返回结果为空");
			MarvelsLogUtil.getInstance().error(">>>>>>orderNumber:"+orderNumber+",代付返回结果为空");
		}
		MarvelsLogUtil.getInstance().info(">>>>>>>>代付交易返回参数" + resultStr);
		String decryptStr = "";
		String returnCode = "";
		String returnMsg = "";
		if (StringUtils.isNotEmpty(resultStr)) {
			String base64De = "";
			try {
				decryptStr = RsaCodingUtil.decryptByPubCerFile(resultStr, cerPath);
				base64De = Base64Util.getFromBASE64Str(decryptStr);
				MarvelsLogUtil.getInstance().info(">>>>>>>代付交易返回参数解析结果" + base64De);
			} catch (Exception e) {
				result.put("status",MarvelsConstant.PROCESSING);
				result.put("errormsg","解析异常");
				return result;
			}
			BaoFuPayTradeResponse baoFuPayTradeResponse = new BaoFuPayTradeResponse();
			baoFuPayTradeResponse = JSON.parseObject(base64De, BaoFuPayTradeResponse.class);
			returnCode = baoFuPayTradeResponse.getTransContent().getTransHead().getReturnCode();
			returnMsg = baoFuPayTradeResponse.getTransContent().getTransHead().getReturnMsg();
			if ("0300".equals(returnCode) || "0000".equals(returnCode) || "200".equals(returnCode)) {// 交易处理中
				result.put("status",MarvelsConstant.PROCESSING);
				result.put("errormsg",returnMsg);
			} else {
				result.put("status",MarvelsConstant.FAILED);
				result.put("errormsg",returnMsg);
			}
			result.put("errorcode",returnCode);
		} else {
			result.put("status",MarvelsConstant.PROCESSING);
			result.put("errormsg","宝付代付返回结果为空");
		}
		return result;
	}

	@Override
	public Map<String, Object> baoFuPayTradeStrtusQuery(BaoFuPayTradeStrtusQueryDTO tradeStrtusQueryDTO) throws MarvelsBusinessException {
		Map<String, Object> hashMap = new HashMap<String, Object>();
		BaoFuPayTradeResponse baoFuPayTradeResponse = new BaoFuPayTradeResponse();
		hashMap.put("member_id",getBfMemberId());
		hashMap.put("terminal_id", getBfTerminalId());
		hashMap.put("data_type", "json");
		hashMap.put("version", "4.0.0");
		JSONArray transReqData = new JSONArray();
		JSONObject obj = new JSONObject();
		obj.put("trans_batchid", tradeStrtusQueryDTO.getTransBatchid());
		obj.put("trans_no", tradeStrtusQueryDTO.getOrignOrderNumber());
		transReqData.add(obj);
		JSONObject transReqData2 = new JSONObject();
		transReqData2.put("trans_reqData", transReqData);
		JSONArray transReqDatas = new JSONArray();
		transReqDatas.add(transReqData2);
		JSONObject transContent = new JSONObject();
		transContent.put("trans_reqDatas", transReqDatas);
		JSONObject transContent2 = new JSONObject();
		transContent2.put("trans_content", transContent);
		String base64Str = "";
		try {
			base64Str = Base64Util.getBASE64(transContent2.toString());
		} catch (UnsupportedEncodingException e1) {
			MarvelsLogUtil.getInstance().error(">>>>>>宝付代付结果查询转base64:",e1);
			throw new MarvelsBusinessException("转base64异常");
		}
		String pfxPath =ServerProperties.getValue(configPropertiesPath, "common.properties", "bf.pfx.path");
		String encryptStr = RsaCodingUtil.encryptByPriPfxFile(base64Str, pfxPath,  getBfPriKeypass());
		hashMap.put("data_content", encryptStr);
		String str = SystemUtil.paramsAssembling(hashMap,ServerProperties.getValue(configPropertiesPath, "common.properties", "bf_pay_checkUrl"));
		MarvelsLogUtil.getInstance().info(">>>>>>代付交易查询请求参数" + str);
		String resultStr = "";
		Map<String, Object> result=new HashMap<String, Object>();
		try {
			resultStr = HttpUtils.baoFuHttpRequest(str);
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error(">>>>>>>宝付代付交易查询响应:",e);
			result.put("status",MarvelsConstant.PROCESSING);
			result.put("errormsg","请求异常");
			return result;
		}
		MarvelsLogUtil.getInstance().info(">>>>>>>代付交易返回参数" + resultStr);
		String cerPath = ServerProperties.getValue(configPropertiesPath, "common.properties", "bf.cer.path");
		String decryptStr = "";
		if (StringUtils.isNotEmpty(resultStr)) {
			String base64De = "";
			try {
				decryptStr = RsaCodingUtil.decryptByPubCerFile(resultStr, cerPath);
				base64De = Base64Util.getFromBASE64Str(decryptStr);
			} catch (Exception e) {
				MarvelsLogUtil.getInstance().error(">>>>>>>宝付代付交易结果查询解码异常:",e);
				result.put("status",MarvelsConstant.PROCESSING);
				result.put("errormsg","解码异常");
				return result;
			}
			MarvelsLogUtil.getInstance().info(">>>>>>>宝付代付交易结果查询返回参数解析结果" + base64De);
			baoFuPayTradeResponse = JSON.parseObject(base64De, BaoFuPayTradeResponse.class);
			String headReturnCode = baoFuPayTradeResponse.getTransContent().getTransHead().getReturnCode();
			String headReturnMsg = baoFuPayTradeResponse.getTransContent().getTransHead().getReturnMsg();
			if (!headReturnCode.equals("0000") && !headReturnCode.equals("200")) {//处理异常状态
				if (headReturnCode.equals("0999")) {// 主机业务繁忙 作交易处理中处理
					result.put("status",MarvelsConstant.PROCESSING);
					result.put("errormsg",headReturnMsg);
				} else {
					result.put("status",MarvelsConstant.FAILED);
					result.put("errormsg",headReturnMsg);
				}
			} else {
				TransReqData transReqDataResponse = baoFuPayTradeResponse.getTransContent().getTransReqDatas().get(0)
						.getTransReqData();
				if (transReqDataResponse.getState().equals("1")) {//// 0：转账中；1：转账成功；-1：转账失败；2：转账退款
					result.put("status",MarvelsConstant.SUCCESS);
					result.put("errormsg",headReturnMsg);
				} else if (transReqDataResponse.getState().equals("0")) {
					result.put("status",MarvelsConstant.PROCESSING);
					result.put("errormsg",headReturnMsg);
				} else {
					result.put("status",MarvelsConstant.FAILED);
					result.put("errormsg",transReqDataResponse.getTransRemark());
				}
			}
			result.put("errorcode",headReturnCode);
		} else {
			result.put("status",MarvelsConstant.PROCESSING);
			result.put("errormsg","宝付代付交易结果查询为空");
		}
		return result;
	}

	@Override
	public Map<String, Object> withHoldTrade(WithHoldTradeDTO withHoldTradeDTO) throws MarvelsBusinessException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Map<String, Object> tradeStatusQuery(Map<String, String> map) throws MarvelsBusinessException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Map<String, Object> baoFuDirectPayment(BaoFuDirectPaymentDTO baoFuDirectPaymentDTO) throws MarvelsBusinessException {
		MarvelsLogUtil.getInstance().info(">>>>>>>>>>宝付协议代扣请求参数:"+JSON.toJSONString(baoFuDirectPaymentDTO));
		String loanId=baoFuDirectPaymentDTO.getLoanId();
		String userId=StringUtils.isEmpty(baoFuDirectPaymentDTO.getUserId())?"":baoFuDirectPaymentDTO.getUserId();
		String bankNumber=baoFuDirectPaymentDTO.getBankNumber();//银行卡号
		String realName=baoFuDirectPaymentDTO.getRealName();//持卡人姓名
		String idNumber=baoFuDirectPaymentDTO.getIdNumber();//身份证
		String mobile=baoFuDirectPaymentDTO.getMobile();//手机号
		String amount=baoFuDirectPaymentDTO.getAmount();//交易金额 
		String orderNumber = baoFuDirectPaymentDTO.getOrderNumber();
		//参数
		//0 是分账版  1 是普通版
		String version =ServerProperties.getValue(configPropertiesPath, "common.properties", "bf.version");
		if(StrUtil.isEmpty(version)){
			version = "1";
		}
		String pfxPath = ServerProperties.getValue(configPropertiesPath, "common.properties", "bf.pfx.path");
		String cerPath = ServerProperties.getValue(configPropertiesPath, "common.properties", "bf.cer.path");
		String callbackurl=ServerProperties.getValue(configPropertiesPath, "common.properties", "bf.xy.payment.callbackurl");
		String requestUrl=ServerProperties.getValue(configPropertiesPath, "common.properties", "bf.xy.request.url");
		String terminalId =getBfTerminalId();
		String memberId=getBfMemberId();
		String priKeyPass=getBfPriKeypass();
		String aes=getBfAesKey();
		String protocolNo=baoFuDirectPaymentDTO.getProtocolNo();
		String dgtlEnvlp="01"+"|"+aes;
		Map<String, String> hashMap = new TreeMap<String, String>();
		hashMap.put("send_time",DateUtils.getDateYYYYMMDDHHMMSS(new Date()));//报文发送日期时间
		hashMap.put("msg_id", SystemUtil.createUUID("BFXYBW"));//报文流水号
		hashMap.put("version", "4.0.0.0");//版本号
		hashMap.put("terminal_id",terminalId);//终端号
		if("0".equals(version)){
			hashMap.put("txn_type", "18");//交易类型  协议支付直接支付类
		}else{
			hashMap.put("txn_type", "08");//交易类型  协议支付直接支付类
		}
		hashMap.put("member_id",memberId);//商户号
		hashMap.put("trans_id",orderNumber);//商户订单号
		Map<String, Object> result=new HashMap<String, Object>();
		try {
			hashMap.put("dgtl_envlp", RsaCodingUtil.encryptByPubCerFile(SecurityUtil.Base64Encode(dgtlEnvlp), cerPath));
		} catch (UnsupportedEncodingException e) {
			result.put("status",MarvelsConstant.FAILED);
			result.put("errormsg","dgtl_envlp字段加密异常");
			return result;
		}
		JSONObject riskItemJson = new JSONObject();
		riskItemJson.put("goodsCategory", "02");// 商品类目 详见附录《商品类目》
		riskItemJson.put("userLoginId", mobile);// 用户在商户系统中的登陆名（手机号、邮箱等标识）
		riskItemJson.put("userEmail",baoFuDirectPaymentDTO.getUserEmail());
		riskItemJson.put("userMobile", mobile);// 用户手机号
		riskItemJson.put("registerUserName", realName);// 用户在商户系统中注册使用的名字
		riskItemJson.put("identifyState", "1");// 用户在平台是否已实名，1：是 ；0：不是
		riskItemJson.put("userIdNo", idNumber);// 用户身份证号
		riskItemJson.put("registerTime", baoFuDirectPaymentDTO.getRegisterTime());// 格式为：YYYYMMDDHHMMSS
		riskItemJson.put("registerIp",baoFuDirectPaymentDTO.getRegisterIp());// 用户在商户端注册时留存的IP
		riskItemJson.put("chName", realName);// 持卡人姓名
		riskItemJson.put("chIdNo", idNumber);// 持卡人身份证号
		riskItemJson.put("chCardNo", bankNumber);// 持卡人银行卡号
		riskItemJson.put("chMobile", mobile);// 持卡人手机
		riskItemJson.put("chPayIp", "127.0.0.1");// 持卡人支付IP
		riskItemJson.put("deviceOrderNo",baoFuDirectPaymentDTO.getDeviceOrderNo());// 加载设备指纹中的订单号
		// 交易类型模块字段
		riskItemJson.put("tradeType", "2");// 交易类型
		riskItemJson.put("customerType", "2");// 加载设备指纹中的订单号
		riskItemJson.put("repaymentDate",baoFuDirectPaymentDTO.getRepaymentDate());// 到期还款日
		riskItemJson.put("lendingRate",baoFuDirectPaymentDTO.getLendingRate());// 借款利率
		riskItemJson.put("bidYields", baoFuDirectPaymentDTO.getBidYields());// 标的收益率
		riskItemJson.put("latestTradeDate",baoFuDirectPaymentDTO.getLatestTradeDate());// 账户前一次交易日期
		hashMap.put("user_id", "");// 用户userId需要和绑卡保持一致
		try {
			hashMap.put("protocol_no", SecurityUtil.AesEncrypt(SecurityUtil.Base64Encode(protocolNo), aes));
		} catch (UnsupportedEncodingException e2) {
			result.put("status",MarvelsConstant.FAILED);
			result.put("errormsg","protocolNo字段加密异常");
			return result;
		} // 签约协议号
		
		if("0".equals(version)){
			String shareInfo = memberId + ","
					+ String.valueOf(
							(new BigDecimal(amount).setScale(2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)))
									.intValue());
			hashMap.put("share_info", shareInfo);// 分账信息
		}
		hashMap.put("txn_amt", String.valueOf((new BigDecimal(amount).setScale(2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100))).intValue()));// 交易金额  分
		hashMap.put("risk_item", riskItemJson.toString());// 风控参数
		hashMap.put("return_url", callbackurl);// 商户订单号
		hashMap.put("req_reserved1", loanId);// 商户保留域1
		String str = FormatUtil.coverMap2String(hashMap);
		String sign = "";
		try {
			String signature = SecurityUtil.sha1X16(str, "UTF-8");// 签名
			sign = SignatureUtils.encryptByRSA(signature, pfxPath, priKeyPass);
		} catch (Exception e) {
			result.put("status",MarvelsConstant.FAILED);
			result.put("errormsg","加签异常");
			return result;
		}
		hashMap.put("signature", sign);// 签名域
		String resultStr = "";
		try {
			MarvelsLogUtil.getInstance().info(">>>>>>>>>>>>>宝付协议代扣请求参数:" + JSON.toJSONString(hashMap));
			resultStr = HttpUtils.RequestForm(requestUrl, hashMap);
			MarvelsLogUtil.getInstance().info(">>>>>>>>>>>>>宝付协议代扣返回参数:" + resultStr);
		} catch (Exception e1) {
			MarvelsLogUtil.getInstance().error(">>>>>>>>>loanId" + loanId + ",idNumber" + idNumber + "宝付协议代扣请求异常:", e1);
			result.put("status",MarvelsConstant.PROCESSING);
			result.put("errormsg","协议代扣请求异常");
			return result;
		}
		String respCode = "";
		String bizRespCode = "";
		String bizRespMsg = "";
		String returnOrderId = "";
		if (StringUtils.isNotEmpty(resultStr)) {
			Map<String, String> returnData = FormatUtil.getParm(resultStr);
			// 返回数据校验签名部分
			String signature = returnData.get("signature");
			returnData.remove("signature");// 移除签名字段
			String returnDataStr = FormatUtil.coverMap2String(returnData);
			String loginSignature = "";
			try {
				loginSignature = SecurityUtil.sha1X16(returnDataStr, "UTF-8");
			} catch (Exception e) {
				MarvelsLogUtil.getInstance().error(">>>>>>>>>loanId" + loanId + ",idNumber" + idNumber + "宝付协议代扣返回结果加签异常:", e);
				result.put("status",MarvelsConstant.PROCESSING);
				result.put("errormsg","协议代扣请求异常");
				return result;
			} // 签名
			if (SignatureUtils.verifySignature(cerPath, loginSignature, signature)) {// 签名一致
				respCode = returnData.get("resp_code");// 应答码
				bizRespCode = returnData.get("biz_resp_code");// 业务应答码
				bizRespMsg = returnData.get("biz_resp_msg");// 业务返回说明
				returnOrderId = returnData.get("order_id");// 宝付订单号
				if ("S".equalsIgnoreCase(respCode)) {// 成功
					result.put("status",MarvelsConstant.SUCCESS);
					result.put("errormsg","交易成功");
				} else if ("F".equalsIgnoreCase(respCode)) {// 失败
					result.put("status",MarvelsConstant.FAILED);
					result.put("errormsg",bizRespMsg);
				} else {// 处理中
					result.put("status",MarvelsConstant.PROCESSING);
					result.put("errormsg",bizRespMsg);
				}
				result.put("errorcode",respCode);
			} else {
				result.put("status",MarvelsConstant.PROCESSING);
				result.put("errormsg","签名不一致");
			}
		}else{
			result.put("status",MarvelsConstant.PROCESSING);
			result.put("errormsg","返回结果为空");
		}
		return result;
	}

	@Override
	public Map<String, Object> baoFuDirectPaymentQuery(BaoFuDirectPaymentQueryDTO directPaymentQueryDTO) throws MarvelsBusinessException {
		//参数
		String pfxPath = ServerProperties.getValue(configPropertiesPath, "common.properties", "bf.pfx.path");
		String cerPath = ServerProperties.getValue(configPropertiesPath, "common.properties", "bf.cer.path");
		String requestUrl= ServerProperties.getValue(configPropertiesPath, "common.properties", "bf.xy.request.url");
		String terminalId =getBfTerminalId();
		String memberId=getBfMemberId();
		String priKeyPass=getBfPriKeypass();
		Map<String, String> hashMap = new TreeMap<String, String>();
		String origTransId = directPaymentQueryDTO.getOrderNumber();
		String sendTime = DateUtils.getDateYYYYMMDDHHMMSS(new Date());// 报文发送日期时间
		hashMap.put("send_time", sendTime);
		hashMap.put("msg_id", SystemUtil.createUUID("BFXYBW"));// 报文流水号
		hashMap.put("version", "4.0.0.0");
		hashMap.put("terminal_id", terminalId);
		hashMap.put("txn_type", "07");// 交易类型
		hashMap.put("member_id",memberId);
		hashMap.put("orig_trans_id", origTransId);// 交易时的trans_id
		hashMap.put("orig_trade_date", sendTime);//
		String SignVStr = FormatUtil.coverMap2String(hashMap);
		String signatureFirst = "";
		String sign = "";
		Map<String, Object> result=new HashMap<String, Object>();
		try {
			signatureFirst = SecurityUtil.sha1X16(SignVStr, "UTF-8");// 签名
			sign = SignatureUtils.encryptByRSA(signatureFirst, pfxPath, priKeyPass);
		} catch (Exception e2) {
			MarvelsLogUtil.getInstance().error(">>>>>>>>>>直接支付查询signature字段签名异常", e2);
			result.put("status",MarvelsConstant.FAILED);
			result.put("errormsg","加签异常");
			return result;
		}
		hashMap.put("signature", sign);// 签名域
		String resultStr = "";
		try {
			MarvelsLogUtil.getInstance().info(">>>>>>>>>>>>>宝付直接支付查询请求参数:" + JSON.toJSONString(hashMap));
			resultStr = HttpUtils.RequestForm(requestUrl, hashMap);
			MarvelsLogUtil.getInstance().info(">>>>>>>>>>>>>宝付直接支付查询请求返回参数:" + resultStr);
		} catch (Exception e1) {
			MarvelsLogUtil.getInstance().error(">>>>>>>>>origTransId" + origTransId + "协议代扣结果查询请求:", e1);
			result.put("status",MarvelsConstant.PROCESSING);
			result.put("errormsg","协议代扣结果查询请求异常");
			return result;
		}
		String respCode = "";
		String bizRespMsg = "";
		String returnOrderId = "";
		if (StringUtils.isNotEmpty(resultStr)) {
			Map<String, String> returnData = FormatUtil.getParm(resultStr);
			// 返回数据校验签名部分
			String signature = returnData.get("signature");
			returnData.remove("signature");// 移除签名字段
			String returnDataStr = FormatUtil.coverMap2String(returnData);
			String loginSignature = "";
			try {
				loginSignature = SecurityUtil.sha1X16(returnDataStr, "UTF-8");
			} catch (Exception e) {
				MarvelsLogUtil.getInstance().error(">>>>>>>>>origTransId" + origTransId + "协议代扣结果查询解签:", e);
				result.put("status",MarvelsConstant.PROCESSING);
				result.put("errormsg","协议代扣结果查询解签异常");
				return result;
			} // 签名
			if (SignatureUtils.verifySignature(cerPath, loginSignature, signature)) {// 签名一致
				respCode = returnData.get("resp_code");// 应答码
				bizRespMsg = returnData.get("biz_resp_msg");// 业务返回说明
				returnOrderId = returnData.get("order_id");// 宝付订单号
				if ("S".equalsIgnoreCase(respCode)) {// 成功
					result.put("status",MarvelsConstant.SUCCESS);
					result.put("errormsg","交易成功");
				} else if ("F".equalsIgnoreCase(respCode)) {// 失败
					result.put("status",MarvelsConstant.FAILED);
					result.put("errormsg",bizRespMsg);
				} else {// 处理中
					result.put("status",MarvelsConstant.PROCESSING);
					result.put("errormsg",bizRespMsg);
				}
				result.put("errorcode",respCode);
			} else {
				result.put("status",MarvelsConstant.PROCESSING);
				result.put("errormsg","签名不一致");
			}
		}
		return result;
	}

	
	/**
	 * 宝付商户号
	 * @return
	 */
	private String getBfMemberId(){
		String merchantNo = null;
		McsmRevealConfigureAppDTO config = mcsmRevealConfigureAppDao.queryConfigByKey("bf.member.id");
		if(config != null && config.getConfigValue() != null && config.getState() == 0){
			merchantNo = config.getConfigValue();
		}
		MarvelsLogUtil.getInstance().info("实时获取宝付商户号：" + merchantNo);
		return merchantNo;
	}

	
	/**
	 * 宝付终端号
	 * @return
	 */
	private String getBfTerminalId(){
		String merchantNo = null;
		McsmRevealConfigureAppDTO config = mcsmRevealConfigureAppDao.queryConfigByKey("bf.terminal.id");
		if(config != null && config.getConfigValue() != null && config.getState() == 0){
			merchantNo = config.getConfigValue();
		}
		MarvelsLogUtil.getInstance().info("实时获取宝付终端号：" + merchantNo);
		return merchantNo;
	}

	/**
	 * 宝付私钥密码
	 * @return
	 */
	private String getBfPriKeypass(){
		String merchantNo = null;
		McsmRevealConfigureAppDTO config = mcsmRevealConfigureAppDao.queryConfigByKey("bf.priKeypass");
		if(config != null && config.getConfigValue() != null && config.getState() == 0){
			merchantNo = config.getConfigValue();
		}
		MarvelsLogUtil.getInstance().info("实时获取宝付私钥密码：" + merchantNo);
		return merchantNo;
	}

	/**
	 * 宝付aesKey
	 * @return
	 */
	private String getBfAesKey(){
		String merchantNo = null;
		McsmRevealConfigureAppDTO config = mcsmRevealConfigureAppDao.queryConfigByKey("bf.aes.key");
		if(config != null && config.getConfigValue() != null && config.getState() == 0){
			merchantNo = config.getConfigValue();
		}
		MarvelsLogUtil.getInstance().info("实时获取宝付aesKey：" + merchantNo);
		return merchantNo;
	}

	@Override
	public void bfPaymentNotify(BfPaymentNotifyDTO paymentNotifyDTO) throws MarvelsBusinessException {
		Map<String, String> returnData =new TreeMap<String, String>();
		returnData = BeanUtils.objectToMap(returnData,paymentNotifyDTO);
		MarvelsLogUtil.getInstance().info(">>>>>>>>宝付支付回调参数:"+JSON.toJSONString(returnData));
		String signature = returnData.get("signature");
		returnData.remove("signature");// 移除签名字段
		String loginSignature = "";
		String returnDataStr = FormatUtil.coverMap2String(returnData);
		try {
			loginSignature = SecurityUtil.sha1X16(returnDataStr, "UTF-8");
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error(">>>>>>>>>trans_id" + returnData.get("trans_id") + "宝付协议代扣结果回调解签:", e);
			throw new MarvelsBusinessException("协议代扣回调解签异常");
		} 
		//验证签名是否一致
		String cerPath = ServerProperties.getValue(configPropertiesPath, "common.properties", "bf.cer.path");
		if (SignatureUtils.verifySignature(cerPath, loginSignature, signature)) {// 签名一致
			this.callBackDeal(returnData);
		} else {
			throw new MarvelsBusinessException("验签不一致");
		}
		
	}
	
	private void callBackDeal(Map<String, String> returnData) throws MarvelsBusinessException {
		String batchName = Thread.currentThread().getId() + "-" + UUID.randomUUID().toString().replace("-", "");
		String  returnOrderId = returnData.get("trans_id");// 宝付订单号
		// 先将交易结果处于处理中的代扣流水详情占用
		int count = detailDao.occupationOrder(batchName,returnOrderId);
		if (count < 1) {
			MarvelsLogUtil.getInstance().info(">>>>>宝付协议代扣回调订单号:" + String.valueOf(returnOrderId) + ",占用订单号失败");
			throw new MarvelsBusinessException("占用订单号失败");
		}
		String respCode = returnData.get("resp_code");// 应答码
		String bizRespCode =returnData.get("biz_resp_code");// 业务返回码
		String bizRespMsg = returnData.get("biz_resp_msg");// 业务返回说明
		String result="";
		if ("S".equalsIgnoreCase(respCode)) {// 成功
			result = "2";
		} else if ("F".equalsIgnoreCase(respCode)) {// 失败
			result = "9";
		} else{
			throw new MarvelsBusinessException("回调状态错误");
		}
		callBusinessDeal(result,batchName,returnOrderId,bizRespCode,bizRespMsg);
	}
	
	/**
	 * 代扣异步回调业务处理 
	 * @param result 2 成功  9 失败
	 * @param batchName 批次号
	 * @param orderNo 订单号
	 * @param errorCode 回调返回code
	 * @param errorMsg 回调返回msg
	 * @throws MarvelsBusinessException
	 */
	private void callBusinessDeal(String result,String batchName,String orderNo,String errorCode,String errorMsg) throws MarvelsBusinessException{
		// 查询出被该批次号占用的代扣流水详情
		List<McfePaymentWithholdDetailDTO> listDTO = detailDao.selectByBatchName(batchName);
		for (McfePaymentWithholdDetailDTO detailDTO : listDTO) {
			String loanId = detailDTO.getLoanId();
			// 查询合同状态
			McfeCustomerLoanContractDTO contractDTO = contractDao.selectContractByLoanId(loanId);
			if (contractDTO.getStatus() != 0 && contractDTO.getStatus() != 1) {
				MarvelsLogUtil.getInstance().info(">>>>>>>>>>loanId:" + loanId + "查询代扣状态时,合同状态不处于还款中");
				McfePaymentWithholdDetailDTO detailDTOUpdate = new McfePaymentWithholdDetailDTO();
				detailDTOUpdate.setId(detailDTO.getId());
				detailDTOUpdate.setUpdatedBy("SYSTEM");
				detailDTOUpdate.setUpdatedDate(new Date());
				detailDTOUpdate.setBatchStatus("2");// 将批次状态改成处理完成
				detailDao.updateByPrimaryKeySelective(detailDTOUpdate);
				continue;
			}
			McfePaymentWithholdDTO withholdDTO = withholdDao.selectByWithholdCode(detailDTO.getWithholdCode());
			if (null == withholdDTO) {
				MarvelsLogUtil.getInstance().info(">>>>>>>>>>loanId:" + loanId + "查询代扣流水无记录");
				McfePaymentWithholdDetailDTO detailDTOUpdate = new McfePaymentWithholdDetailDTO();
				detailDTOUpdate.setId(detailDTO.getId());
				detailDTOUpdate.setUpdatedBy("SYSTEM");
				detailDTOUpdate.setUpdatedDate(new Date());
				detailDTOUpdate.setBatchStatus("2");// 将批次状态改成处理完成
				detailDao.updateByPrimaryKeySelective(detailDTOUpdate);
				continue;
			}
			McfeRepaymentTradeDetails mcamRepaymentTradeDetails = mcamRepaymentTradeDetailsMapper
					.selectByOrderNum(orderNo);
			if (mcamRepaymentTradeDetails == null) {
				throw new MarvelsBusinessException("交易记录不存在");
			}
			String tradeResult = mcamRepaymentTradeDetails.getResult();
			if ("0".equals(tradeResult) || "-3".equals(tradeResult) || "-4".equals(result)
					|| "-1".equals(tradeResult)) {
				throw new MarvelsBusinessException("交易记录状态不处于交易中");
			}
			if (StringUtils.isNotEmpty(result) && result.equals("2")) {
				mcamRepaymentTradeDetails.setSuccessTime(DateUtils.getDateStr(new Date(), "yyyy-MM-dd HH:mm:ss"));
			}
			mcamRepaymentTradeDetails.setPayNumReturn(orderNo);
			mcamRepaymentTradeDetails.setResult(result.equals("2") ? MarvelsConstant.SUCCESS : MarvelsConstant.FAILED);
			mcamRepaymentTradeDetails.setErrorCode(errorCode);
			mcamRepaymentTradeDetails.setErrorMsg(errorMsg);
			mcamRepaymentTradeDetailsMapper.updateByPrimaryKeySelective(mcamRepaymentTradeDetails);
			// 更新代扣流水
			McfePaymentWithholdDetailDTO detailDTOUpdate = new McfePaymentWithholdDetailDTO();
			detailDTOUpdate.setId(detailDTO.getId());
			detailDTOUpdate.setUpdatedBy("SYSTEM");
			detailDTOUpdate.setUpdatedDate(new Date());
			detailDTOUpdate.setStatus(result);// 1交易中; 2代扣成功 9代扣失败
			detailDTOUpdate.setRtnOrderNo(orderNo);
			String paymentChannel = ServerProperties.getValue(configPropertiesPath, "common.properties",
					"payment_channel");
			detailDTOUpdate.setResChannel(paymentChannel);
			detailDTOUpdate.setRtnResponseDate(new Date());
			detailDTOUpdate.setBatchStatus("2");// 将批次状态改成处理完成
			detailDTOUpdate.setRtnResponseCode(errorCode);// 扣款返回码
			detailDTOUpdate.setRtnResponseMsg(errorMsg);// 扣款返回信息
			if ("2".equals(result)) {// 成功
				detailDTOUpdate.setAmountAct(detailDTO.getAmount());
			}
			detailDao.updateByPrimaryKeySelective(detailDTOUpdate);
			if ("2".equals(result)) {// 成功
				detailDTOUpdate.setTransctionSeq(detailDTO.getTransctionSeq());
				try {
					MarvelsLogUtil.getInstance().info(">>>>>>>>>>>>>>loanId" + loanId + "汇聚代扣回调结果为成功处理开始");
					withholdDTO.setRepayStyle(withholdDTO.getPayType() + "");
					withholdDTO.setFlowPayType("1");
					withholdPaymentApi.withholdSuccess(contractDTO, withholdDTO, detailDTOUpdate);
				} catch (Exception e) {
					MarvelsLogUtil.getInstance().error(">>>>>>代扣成功处理异常:", e);
				}
			}
			// 更新代扣总记录
			McfePaymentWithholdDTO withholdDTOUpdate = new McfePaymentWithholdDTO();
			withholdDTOUpdate.setId(withholdDTO.getId());
			BigDecimal successAmount = new BigDecimal("0");
			if ("2".equals(result)) {// 成功
				successAmount = detailDTO.getAmount();
			}
			// 查询代扣详情表中的处理中的数据
			int countFail = detailDao.countDealingByWithholdCode(detailDTO.getWithholdCode());
			BigDecimal amountAct = (withholdDTO.getAmountAct() == null ? BigDecimal.ZERO : withholdDTO.getAmountAct())
					.add(successAmount);
			if (withholdDTO.getAmount().doubleValue() <= amountAct.doubleValue()) {
				withholdDTOUpdate.setStatus("1");// 代扣成功
			} else if (countFail > 0) {
				withholdDTOUpdate.setStatus("2");// 代扣中
			} else {
				withholdDTOUpdate.setStatus("9");// 代扣失败
			}
			withholdDTOUpdate.setUpdatedBy("SYSTEM");
			withholdDTOUpdate.setUpdatedDate(new Date());
			withholdDTOUpdate.setAmountAct(amountAct);
			withholdDao.updateByPrimaryKeySelective(withholdDTOUpdate);
			MarvelsLogUtil.getInstance().info(">>>>>>>>>>>>>>loanId" + loanId + "汇聚代扣回调处理成功");
		}
	}
	
	public static void main(String[] args) {
		BfPaymentNotifyDTO paymentNotifyDTO=new BfPaymentNotifyDTO();
		paymentNotifyDTO.setResp_code("S");
		paymentNotifyDTO.setTerminal_id("200001412");
		paymentNotifyDTO.setMember_id("100026283");
		paymentNotifyDTO.setBiz_resp_code("0000");
		paymentNotifyDTO.setBiz_resp_msg("交易成功");
		paymentNotifyDTO.setOrder_id("415330943");
		paymentNotifyDTO.setTrans_id("BFXYDK155062578180116275");
		paymentNotifyDTO.setSucc_amt("35000");
		paymentNotifyDTO.setSucc_time("2019-02-20 09:15:33");
		paymentNotifyDTO.setSignature("59dc39a6a07e0cc9127e429ceec35e7bdaa3a09af0792855241711049fdf4e1556c2460e9358aa934afd149816fcc9c43cccf6b858d52d354eef44b1fbb744178f6ade1b49d9d3daa66ba3fd04646f000f8f4851609d300acdfe0d75233c23ead4d5ac58c5b881ab514306500d4d1eefeb9a9df60266d40967efb3b44bcfa815");
		Map<String, String> returnData =new TreeMap<String, String>();
		returnData = BeanUtils.objectToMap(returnData,paymentNotifyDTO);
		String signature = returnData.get("signature");
		returnData.remove("signature");// 移除签名字段
		String loginSignature = "";
		String returnDataStr = FormatUtil.coverMap2String(returnData);
		try {
			loginSignature = SecurityUtil.sha1X16(returnDataStr, "UTF-8");
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error(">>>>>>>>>trans_id" + returnData.get("trans_id") + "宝付协议代扣结果回调解签:", e);
		} 
		//验证签名是否一致
		if (SignatureUtils.verifySignature("D:/eclipse/workspace/marvels-core-v2-simple-1.0.0/marvels-core-approve/src/main/resources/dev/cer/baofu/bfkey_100026283@@200001412.cer", loginSignature, signature)) {// 签名一致
			System.out.println(">>>>>>>>验证签名一致");
		}else{
			System.out.println(">>>>>>>>验证签名不一致");
		}
		System.out.println(">>>>>>>>宝付支付回调参数:"+JSON.toJSONString(returnData));
		String string="109ee4d68289cf5bdb0a87ea1e0cca7ef1df7329c3fbf599f62b7f95f66ba372d7f2a6d818913a558eb61627f43499b78058cbcfa454dd52a8458b5f755295890ac6f36d713e596bb2698c29f62c53b90a7003372bb08978aa2193c77aefe9f59eb12ab766de097d556c80889455504c1c85502329f171e43b87e58998e073f2ac16fd86c41f7f98ede78302b7b3f0fc578a011abf30a28bb41c4f28afe8dd2afb6be05841d3afbc33a4093a968288abb9db307da8d08ff7a699238bc422b615b78f4623c00b602b084ce31c0f35c3b75ec3488f78326994fca2b87a37f4a2f4515874789987f3dd55fd7fde7cd7d124dbcd7712b5c73aa43b214c7cccf6de4077789f1e2e5cd6ea0a79e1a68b1180637c96ee7be4bf4b3a67bf11e8d8e04e5549c002a899dcdf9e34839e6c034c28a052531414cc7e8f1b612246e34e84f44230939868afa1d77662f3450712914ad5c5332cb5b90989c1426bc27cefdc795890e649c7b3d16a577da9d7ea14e770ed35d256d178be2bdc2cb8b3cd575c4a3ba54c0e6c36e63f52d480ec5ca271048ac28e0747aa2415f68e0ed222abf05026384b93cfed3a78a767225b5f3c825999b6b5e934238f9a2d8b2eedabd9f09f8065aa80f51432f392669f27954cca6f40db993f9452140c804afa1dceaea8d6bc92fafb2ad921f1fe80841ae3f9a1d6e94482df747ced578b7960b243af7f8832848f58c5b9966a2f8aed5ef969238bfdd56fd7ce3dca448a158a0faac81a4dccbac635a93f9bd58cf5704832526514b19d00c6657930654d0987b790c32e3293a3c29646b3a7438c8893a81887f7fc63f943f4b6db81d9b8eee977ba7f252f2820e99235112159f41a7a2bac50fba950eadd77522dcd798cdad1e2fbeb72fb6bd35d4f019d2729c043a40bf4dd5ac896b96eaa7194fe74dcf519e8925230d0a2fd0330d83af9553b7e46093b52ad020535b5cc719cf6976f47c6b304b014c216dc232f23a473026b792f7a98c7e0b43affa48f5fd86da8af70b42b35a37a127dfd4113545cb15e36f7abeeb068ff8fae76b303e07cc345b60805ec25e5e941898082ce74e954dafde90a874f53c7a19ef306e28f4cc457ec5cf1ea3228aff3e2daa6b29524527dcdff3ba70ffb3c8de2c16865f891fd6ade1c608b07e8194bb62c5bff62ee49377cceaaa4666db7660e7615e1e2209d9181658a81b6f77bad8ca057181a5633ffd7f16a14489ce212bfd1e23f1f0c34034a9d58fa33eec0d0ada6b280b725f5b7acda9890ff72097837b829e07265c1eb58a75205e47384dd4420b9a6d5ec4b7c3c88c749b1f039e8decd1231198172743a663629f5f873b9712b36fce36b3f0f4343abeb5532130c54114176af4e1b7dfafce4920b1713c11272668ee191ca819ab840232260cfad2e3581657c4b3f64ac96a1ba4a322e294f";
		String decryptStr="";
		String base64De="";
		decryptStr = RsaCodingUtil.decryptByPubCerFile(string, "D:/eclipse/workspace/marvels-core-v2-simple-1.0.0/marvels-core-approve/src/main/resources/dev/cer/baofu/bfkey_100026283@@200001412.cer");
		try {
			base64De = Base64Util.getFromBASE64Str(decryptStr);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		BfPaymentCallBackContentDTO callBackDTO=SystemUtil.xmlToEntity2(base64De, BfPaymentCallBackContentDTO.class);
		BfPaymentCallBackContentDTO.TransReqDatas.TransReqData transReqData=callBackDTO.getTransReqDatas().getTransReqData().get(0);
		String status=transReqData.getState();
	}

	@Override
	public void bfPaymentCallBack(BfPaymentCallBackDTO bfPaymentCallBackDTO) throws MarvelsBusinessException {
		String decryptStr="";
		String base64De="";
		String cerPath = ServerProperties.getValue(configPropertiesPath, "common.properties", "bf.cer.path");
		try {
			decryptStr = RsaCodingUtil.decryptByPubCerFile(bfPaymentCallBackDTO.getData_content(), cerPath);
			base64De = Base64Util.getFromBASE64Str(decryptStr);
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error("代付结果异步回调解密异常", e);
			throw new MarvelsBusinessException("代付结果异步回调解密异常");
		}
		MarvelsLogUtil.getInstance().info(">>>代付结果异步回调解密后:"+base64De);
		BfPaymentCallBackContentDTO callBackDTO=SystemUtil.xmlToEntity2(base64De, BfPaymentCallBackContentDTO.class);
		BfPaymentCallBackContentDTO.TransReqDatas.TransReqData transReqData=callBackDTO.getTransReqDatas().getTransReqData().get(0);
		String status=transReqData.getState();
		String auditStatus="";
		if(status.equals("1")){//2：转账成功
			auditStatus="F2";
		}else if(status.equals("-1") || status.equals("2")){// -1：转账失败  2：转账退款
			auditStatus="F3";
		}else{
			throw new MarvelsBusinessException("代付异步回调状态异常");
		}
		this.paymentCallBackDeal(transReqData.getTransNo(),auditStatus,status,transReqData.getTransRemark());
	}
	
	
	
	/**
	 * 代付异步回调结果处理
	 * @param orderNumber  订单号
	 * @param auditStatus 审核状态
	 * @param returnStatus 返回状态
	 * @param auditMsg  返回错误信息
	 * @throws MarvelsBusinessException
	 */
	private void paymentCallBackDeal(String orderNumber,String auditStatus,String returnStatus,String auditMsg) throws MarvelsBusinessException{
		long threadId = Thread.currentThread().getId();
		MarvelsLogUtil.getInstance().info(">>>>>>>>>>线程号:" + threadId + "宝付代付结果异步回调参数开始");
		// 先锁住一批需要放款的数据
		String batName = threadId + UUID.randomUUID().toString().replace("-", "");
		int count = mcfeLendingProcessMapper.updateAuditInfo(batName, String.valueOf(threadId), "F10",null,orderNumber);// 支付中
		if (count < 1) {// 订单号不处于查询状态
			MarvelsLogUtil.getInstance().info(">>>>>宝付代付结果异步回调订单号:" + orderNumber + ",占用订单号失败");
			throw new MarvelsBusinessException("占用订单号失败");
		}
		// 查询出当前批次锁住的需要放款的数据
		List<McfeLendingProcess> list = mcfeLendingProcessMapper.selectByBatName(batName, String.valueOf(threadId),"F10");
		if (list != null && list.size() > 0) {
			for (McfeLendingProcess mcfeLendingProcess : list) {
				String loanId = mcfeLendingProcess.getLoanId();
				MarvelsLogUtil.getInstance().info(">>>>>>>>>>线程号:" + threadId + ",loanId" + loanId + "宝付代付结果异步回调处理开始");
				McamLoanApplyInfoDTO mcamLoanApplyInfo = new McamLoanApplyInfoDTO();
				mcamLoanApplyInfo.setLoanId(loanId);
				McamLoanApplyInfoDTO mcamLoanApplyInfoDTO = consumerApproveApi.selectLoanApplyInfo(mcamLoanApplyInfo);
				if (!"F03".equalsIgnoreCase(mcamLoanApplyInfoDTO.getStatus())) {// 先判断该笔放款在进件表中是否处于待放款状态
					MarvelsLogUtil.getInstance()
							.info(">>>>>>>>>>>>>>loanId" + loanId + ",手动放款的放款时进件表状态:" + mcamLoanApplyInfoDTO.getStatus());
					continue;
				}
				McfeRepaymentTradeDetails mcamRepaymentTradeDetails = mcamRepaymentTradeDetailsMapper.selectByOrderNum(orderNumber);
				if(mcamRepaymentTradeDetails == null){
					throw new MarvelsBusinessException("交易记录不存在");
				}
				String result = mcamRepaymentTradeDetails.getResult();
				if("0".equals(result) || "-3".equals(result) || "-4".equals(result) || "-1".equals(result)){
					throw new MarvelsBusinessException("交易记录状态不处于交易中");
				}
				mcamRepaymentTradeDetails.setPayNumReturn(orderNumber);
				mcamRepaymentTradeDetails.setResult(auditStatus.equals("F2")?MarvelsConstant.SUCCESS:MarvelsConstant.FAILED);
				mcamRepaymentTradeDetails.setErrorCode(returnStatus);
				mcamRepaymentTradeDetails.setErrorMsg(auditMsg);
				mcamRepaymentTradeDetailsMapper.updateByPrimaryKeySelective(mcamRepaymentTradeDetails);
				if("F2".equals(auditStatus)){//成功
					//放款成功
					mcamRepaymentTradeDetails.setSuccessTime(DateUtils.getDateStr(new Date(), "yyyy-MM-dd HH:mm:ss"));
					//新增 ac_loan_apply_info 	money_hand_out_uid
					try {
						MarvelsLogUtil.getInstance().info(">>>>>>>>>>>>>>loanId" + loanId +"宝付代付结果异步回调结果为成功处理开始");
						McfeLendingProcess process = new McfeLendingProcess();
						String reloanFlag =  consumerLoanApplyApi.synchroMoneyHandOutTime(loanId);
						process.setReloanFlag(reloanFlag);
						process.setLoanId(loanId);
						mcfeLendingProcessMapper.updateAuditResult(process);
					} catch (Exception e) {
						MarvelsLogUtil.getInstance().error(">>>>>>>>>>loanId:" + loanId + "同步到进件表的放款时间失败:", e);
					}
					loanPaymentApi.loanSuccessDeal(mcfeLendingProcess);
				}
				//记录放款日志
				loanAuditApi.auditCommonDeal(loanId, auditStatus, mcfeLendingProcess.getStatus(), "放款异步回调", null);
				// 持久化审核信息
				McfeLendingProcess process = new McfeLendingProcess();
				process.setLoanId(loanId);
				process.setMsg( auditMsg);
				process.setStatus(auditStatus);
				if("F2".equals(auditStatus)){
					//自动放款成功
					process.setPassTime(new Date());
					//新增 ac_loan_apply_info 	money_hand_out_uid
					try {
						String reloanFlag =  consumerLoanApplyApi.synchroMoneyHandOutTime(loanId);
						process.setReloanFlag(reloanFlag);
					} catch (Exception e) {
						MarvelsLogUtil.getInstance().error(">>>>>>>>>>loanId:" + loanId + "同步到进件表的放款时间失败:", e);
					}
				}
				process.setUpdatedBy("system");
				process.setOriginalStatus(mcfeLendingProcess.getStatus());
				process.setLoanId(loanId);
				process.setIsBusy("0");// 将审核状态改为空闲
				int countInsert = mcfeLendingProcessMapper.updateAuditResult(process);
				if (countInsert < 1) {
					MarvelsLogUtil.getInstance().info(">>>>>>>>>>>>>>loanId" + loanId + ",持久化审核信息失败");
					throw new MarvelsBusinessException("代付结果查询持久化审核信息失败");
				}
				MarvelsLogUtil.getInstance().info(">>>>>>>>>>>>>>loanId" + loanId +"宝付代付结果异步回调处理成功");
			}
		}
	}
}
